import asyncio

# 实现异步上下文管理器
# 需要实现两个方法: __aenter__()和__aexit__()
class AsyncContextManager:
    async def __aenter__(self):
        print("进入异步上下文管理器")
        # 模拟耗时
        await asyncio.sleep(1)
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        print("退出异步上下文管理器")
        # 模拟耗时
        await asyncio.sleep(1)

async def main():
    # 异步上下文管理器使用时在with前加上async，要求管理器实现了__aenter__()和__aexit__()方法
    async with AsyncContextManager() as manager:
        print("处理中...")

# 启动并执行异步函数main()
asyncio.run(main())

print("=" * 50)
# 常见异步上下文管理器的库使用
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    html = await fetch("https://www.baidu.com")
    print(html)
asyncio.run(main())

print("=" * 50)
# 实现异步迭代器
class AsyncIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    # 这里的__aiter__()方法返回self，表示当前对象是一个异步迭代器，前面不要加上async
    def __aiter__(self):
        return self
    async def __anext__(self):
        if self.current > self.end:
            raise StopAsyncIteration
        value = self.current
        self.current += 1
        await asyncio.sleep(1)  # 模拟异步耗时
        return value

async def main():
    async for i in AsyncIterator(1, 5):
        print("异步迭代输出：", i)

asyncio.run(main())

print("=" * 50)
# 常见的异步迭代器
import aiofiles
async def read_file():
    async with aiofiles.open("../resources/demo.txt", "r", encoding="utf-8") as f:
        async for line in f:    # 异步迭代
            print(line.strip())

asyncio.run(read_file())

print("=" * 50)
# 异步生成器
async def async_generator():
    for i in range(5):
        await asyncio.sleep(1)
        yield i

async def main():
    async for number in async_generator():
        print("使用异步生成器生成值:", number)

asyncio.run(main())